home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
ab20
/
sounds
/
tools
/
ulaw2svx.lzh
/
Ulaw28SVX.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-27
|
6KB
|
258 lines
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <libraries/asl.h>
#include <libraries/iffparse.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/asl.h>
#include <proto/dos.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <clib/macros.h>
int ulaw2linear(unsigned char);
void maketable(signed char *, int);
int getscale(void);
void CloseAll(void);
/*----------------------------------------------------------------------*/
/* IFF 8SVX Stuff */
/*----------------------------------------------------------------------*/
#define BUFSIZE 64000
#define ID_8SVX MAKE_ID('8','S','V','X')
#define ID_VHDR MAKE_ID('V','H','D','R')
#define ID_BODY MAKE_ID('B','O','D','Y')
typedef LONG Fixed;
/* A fixed-point value, 16 bits to the left of the point and 16 */
/* to the right. A Fixed is a number of 216ths, i.e. 65536ths. */
#define Unity 0x10000L /* Unity = Fixed 1.0 = maximum volume */
/* sCompression: Choice of compression algorithm applied to the samples */
#define sCmpNone 0 /* not compressed */
#define sCmpFibDelta 1 /* Fibonacci-delta encoding */
/* Can be more kinds in the future. */
typedef struct {
ULONG oneShotHiSamples, /* # samples in the high octave 1-shot part */
repeatHiSamples, /* # samples in the high octave repeat part */
samplesPerHiCycle;/* # samples/cycle in high octave, else 0 */
UWORD samplesPerSec; /* data sampling rate */
UBYTE ctOctave, /* # octaves of waveforms */
sCompression; /* data compression technique used */
Fixed volume; /* playback volume from 0 to Unity (full */
/* volume). Map this value into the output */
/* hardware's dynamic range. */
} Voice8Header;
Voice8Header V8H = { 0, 0, 32, 8363, 1, sCmpNone, Unity };
typedef ULONG ID;
typedef struct {
ID ckID;
LONG ckSize; /* sizeof(ckData) */
} Chunk;
Chunk Form, V8Hdr, Body;
/********************************************************************************/
BPTR fpi, fpo;
int size;
unsigned char *buf;
struct IntuitionBase *IntuitionBase;
struct Library *AslBase;
struct FileRequester *FR;
struct EasyStruct ES1 = {
sizeof(struct EasyStruct),
0,
"Error",
"Can't %s",
"EXIT"
};
/*--------------------------------------------------------------------------*/
/* The following routine was extracted from posting by Brian Foley. */
/* Brian Foley email: bfoley@greatlakes.Central.Sun.COM */
/* Systems Engineer smail: 1000 Town Center */
/* Sun Microsystems Suite 1700 */
/* GreatLakes Region Southfield, MI 48075 (313) 352-7070 */
/*--------------------------------------------------------------------------*/
int ulaw2linear(unsigned char ulawbyte)
{
static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
int sign, exponent, mantissa, sample;
ulawbyte = ~ulawbyte;
sign = ulawbyte & 0x80;
exponent = (ulawbyte >> 4) & 0x07;
mantissa = ulawbyte & 0x0F;
sample = exp_lut[exponent] + (mantissa << (exponent + 3));
if ( sign ) sample = -sample;
return sample;
}
int getscale(void)
{
int count, max = 0, i;
size = 0;
do {
count = Read(fpi, buf, BUFSIZE);
size += count;
for ( i = 0; i < count; i++ ) {
max = MAX(ABS(ulaw2linear(buf[i])), max);
}
} while ( count == BUFSIZE );
return max;
}
void maketable(signed char *logs, int max)
{
int i, c, d;
for ( i = 0; i < 256; i++ ) {
c = ( ulaw2linear(i) * ulaw2linear(0) ) / max;
d = ABS(c) & 0xFF;
if ( d > 0x7F ) {
if ( c > 0 ) {
logs[i] = (signed char) ( c / 256 + 1 );
}
else {
logs[i] = (signed char) ( c / 256 - 1 );
}
}
else {
logs[i] = (signed char) ( c / 256 );
}
}
}
void CloseAll(void)
{
if ( FR ) FreeAslRequest(FR);
if ( buf ) FreeMem(buf, BUFSIZE);
if ( fpi ) Close(fpi);
if ( fpo ) Close(fpo);
if ( IntuitionBase ) {
DisplayBeep(NULL);
CloseLibrary((struct Library *) IntuitionBase);
}
if ( AslBase ) CloseLibrary((struct Library *) AslBase);
exit(0);
}
void main(int argc, char **argv)
{
int i, count, max;
char ifile[80], ofile[80];
signed char logs[256];
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37);
if ( ! IntuitionBase ) exit(10);
AslBase = OpenLibrary(AslName, 0);
if ( ! AslBase ) CloseAll();
if ( argc == 0 ) {
FR = AllocFileRequest();
if ( ! FR ) {
CloseAll();
}
if ( AslRequestTags(FR, ASL_Hail, "Input File", TAG_DONE) ) {
strmfp(ifile, FR->rf_Dir, FR->rf_File);
}
else CloseAll();
if ( AslRequestTags(FR, ASL_Hail, "Output File", TAG_DONE) ) {
strmfp(ofile, FR->rf_Dir, FR->rf_File);
}
else CloseAll();
}
else if ( argc != 3 ) {
FPuts(Output(), "Usage: ");
FPuts(Output(), argv[0]);
FPuts(Output(), " infile outfile\n"
"Converts from SPARC ULAW to RAW sound format\n");
exit(0);
}
else {
strcpy(ifile, argv[1]);
strcpy(ofile, argv[2]);
}
fpi = Open(ifile, MODE_OLDFILE);
if ( ! fpi ) {
EasyRequest(NULL, &ES1, NULL, "open infile");
CloseAll();
}
fpo = Open(ofile, MODE_NEWFILE);
if ( ! fpo ) {
EasyRequest(NULL, &ES1, NULL, "open outfile");
CloseAll();
}
buf = (UBYTE *) AllocMem(BUFSIZE, MEMF_PUBLIC);
if ( ! buf ) {
EasyRequest(NULL, &ES1, NULL, "alloc buffer");
CloseAll();
}
max = getscale();
Seek(fpi, 0, OFFSET_BEGINNING);
maketable(logs, max);
Form.ckID = ID_FORM;
Form.ckSize = 4 + sizeof(Chunk) * 2 + sizeof(Voice8Header) + size;
Write(fpo, &Form, 8);
i = ID_8SVX;
Write(fpo, &i, 4);
V8Hdr.ckID = ID_VHDR;
V8Hdr.ckSize = sizeof(Voice8Header);
Write(fpo, &V8Hdr, 8);
V8H.oneShotHiSamples = size;
Write(fpo, &V8H, sizeof(Voice8Header));
Body.ckID = ID_BODY;
Body.ckSize = size;
Write(fpo, &Body, 8);
do {
count = Read(fpi, buf, BUFSIZE);
for ( i = 0; i < count; i++ ) {
buf[i] = logs[buf[i]];
}
if ( count ) Write(fpo, buf, count);
} while ( count == BUFSIZE );
CloseAll();
}